#include "Functions/TerminalIO.h"
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdio.h>
using namespace std;

void BOSS_Afterburner::TerminalIO::PrintDebug(const char* file, int line, const char* func)
{
  if(func)
    ColourPrint(104, Form("DEBUG: %s:%d [%s]", file, line, func));
  else
    ColourPrint(104, Form("DEBUG: %s:%d", file, line));
}

/// Print a message in a certain colour.
void BOSS_Afterburner::TerminalIO::ColourPrint(const char code, const TString& message,
                                               const TString& qualifier)
{
  if(qualifier.Length()) fprintf(stderr, "\033[1;%dm%s: \033[0m", code, qualifier.Data());
  fprintf(stderr, "\033[%dm%s\033[0m\n", code, message.Data());
}

void BOSS_Afterburner::TerminalIO::CheckMainArguments(int argc, char* argv[], int required)
{
  if(argc == 1 || argc > required + 2)
    PrintFatalError(Form("This script needs %d argument(s)", required));
}

/// Print a **bold** message.
void BOSS_Afterburner::TerminalIO::PrintBold(const TString& message)
{
  fprintf(stderr, "\033[1m%s\033[0m\n", message.Data());
}

/// Print a **header** message.
void BOSS_Afterburner::TerminalIO::PrintHeader(const TString& message, char sign)
{
  stringstream ss;
  ss << setw(message.Length() + 8) << setfill(sign) << "" << setfill(' ');
  cerr << endl << endl;
  PrintBold(ss.str().c_str());
  PrintBold("--- " + message + " ---");
  PrintBold(ss.str().c_str());
}

/// Print a **fatal error** message (that is, one that terminates) in red.
/// @warning Calling this function will terminate the entire programme.
void BOSS_Afterburner::TerminalIO::PrintFatalError(const TString& message)
{
  ColourPrint(31, message, "FATAL ERROR");
  terminate();
}

/// Print an **error** message in red.
void BOSS_Afterburner::TerminalIO::PrintError(const TString& message)
{
  ColourPrint(31, message, "ERROR");
}

/// Print a **success** message in green.
void BOSS_Afterburner::TerminalIO::PrintSuccess(const TString& message)
{
  ColourPrint(32, message);
}

/// Print a **warning** message in yellow.
void BOSS_Afterburner::TerminalIO::PrintWarning(const TString& message)
{
  ColourPrint(33, message, "WARNING");
}

/// Auxiliary function that you can used in other functions to check if a pointer that you fed it is a nullpointer. It is useful to use this function if you want to print output when you are incidentally using an empty pointer.
bool BOSS_Afterburner::TerminalIO::IsEmptyPtr(void* ptr)
{
  if(!ptr)
  {
    PrintWarning("Fed a nullpointer");
    return true;
  }
  return false;
}